#include "AdminUserManager.h"
#include "AdminUser.h"
#include "AdminConfiguration.h"

AgoraAdmin::IUserManager*	AgoraAdmin::UserManager::_instance = NULL;

AgoraAdmin::UserManager::UserManager()
{
	//this->LoadUser(); pas utile on load pas tout les users, en memoire on a que ceux connectes
	// finalement si
	this->LoadUser();
}

AgoraAdmin::IUserManager*	AgoraAdmin::UserManager::GetUserManager()
{
	if (UserManager::_instance == NULL)
		UserManager::_instance = new UserManager();
	return UserManager::_instance;
}

std::map<unsigned int, AgoraAdmin::IUser*>*		AgoraAdmin::UserManager::GetUser()
{
	return &(this->_user);
}

AgoraAdmin::IUser*			AgoraAdmin::UserManager::GetUser(unsigned int id)
{
	//std::list<IUser*>::iterator	iteCurrent = this->_user.begin();
	//std::list<IUser*>::iterator	iteEnd = this->_user.end();

	//while (iteCurrent != iteEnd)
	//{
	//	if ((*iteCurrent)->GetId() == id)
	//		return *iteCurrent;
	//	++iteCurrent;
	//}
	//return NULL;
	if (this->_user.count(id))
		return this->_user[id];
	return NULL;
}

AgoraAdmin::IUser*			AgoraAdmin::UserManager::GetUser(std::string& login)
{
	std::map<unsigned int, IUser*>::iterator	iteCurrent = this->_user.begin();
	std::map<unsigned int, IUser*>::iterator	iteEnd = this->_user.end();

	while (iteCurrent != iteEnd)
	{
		if ((*iteCurrent).second->GetLogin() == login)
			return (*iteCurrent).second;
		++iteCurrent;
	}
	return NULL;
}

void	AgoraAdmin::UserManager::LoadUser()
{
	this->UnloadUser();
	IDatabase::DbResult* result = Configuration::GetConfiguration()->GetDatabase()->SelectAllUser();
	for (unsigned int idx = 0; idx < result->size(); idx++)
		this->_user[(*result->at(idx))["id"]->GetValueInt()] = new User((*result->at(idx))["id"]->GetValueInt(), (*result->at(idx))["login"]->GetValueString(), (*result->at(idx))["password"]->GetValueString());
	delete result;
}

AgoraAdmin::IUser*	AgoraAdmin::UserManager::LoadUser(const unsigned int id)
{
	this->UnloadUser(id);
	IDatabase::DbResult* result = Configuration::GetConfiguration()->GetDatabase()->SelectUser(id);
	if (result->size() == 1)
	{
		IUser* user = new User(id, (*result->at(0))["login"]->GetValueString(), (*result->at(0))["password"]->GetValueString());
		this->_user[user->GetId()] = user;
		delete result;
		return user;
	}
	////else //error
	delete result;
	return NULL;
}

AgoraAdmin::IUser*	AgoraAdmin::UserManager::LoadUser(const std::string& login)
{
	IDatabase::DbResult* result = Configuration::GetConfiguration()->GetDatabase()->SelectUser(login);
	if (result->size() == 1)
	{
		IUser* user = new User((*result->at(0))["id"]->GetValueInt(), (*result->at(0))["login"]->GetValueString(), (*result->at(0))["password"]->GetValueString());
		this->_user[user->GetId()] = user;
		delete result;
		return user;
	}
	////else //error
	delete result;
	return NULL;
}

void	AgoraAdmin::UserManager::UnloadUser()
{
	std::map<unsigned int, IUser*>::iterator	iteCurrent = this->_user.begin();
	std::map<unsigned int, IUser*>::iterator	iteEnd = this->_user.end();

	while (iteCurrent != iteEnd)
	{
		Configuration::GetConfiguration()->GetDatabase()->UpdateUser((*iteCurrent).second->GetId(), (*iteCurrent).second->GetLogin(), (*iteCurrent).second->GetPassword());
		delete (*iteCurrent).second;
		++iteCurrent;
	}
	this->_user.clear();
}

void	AgoraAdmin::UserManager::UnloadUser(const unsigned int id)
{
	Configuration::GetConfiguration()->GetDatabase()->UpdateUser(this->_user[id]->GetId(), this->_user[id]->GetLogin(), this->_user[id]->GetPassword());
	delete this->_user[id];
	this->_user.erase(id);
}

AgoraAdmin::IUser*	AgoraAdmin::UserManager::CreateUser(const std::string& login, const std::string& password)
{
	unsigned int id = Configuration::GetConfiguration()->GetDatabase()->CreateUser(login, password);
	IUser *user = new User(id, login, password);
	this->_user[user->GetId()] = user;
	return user;
}

void	AgoraAdmin::UserManager::DeleteUser()
{
	//remove de la base tout les users
	Configuration::GetConfiguration()->GetDatabase()->DeleteAllUser();
	//delete des users
	std::map<unsigned int, IUser*>::iterator	iteCurrent = this->_user.begin();
	std::map<unsigned int, IUser*>::iterator	iteEnd = this->_user.end();

	while (iteCurrent != iteEnd)
	{
		delete (*iteCurrent).second;
		++iteCurrent;
	}
	this->_user.clear();
}

void	AgoraAdmin::UserManager::DeleteUser(const unsigned int id)
{
	//remove de la base un user
	Configuration::GetConfiguration()->GetDatabase()->DeleteUser(id);
	IUser* user = this->GetUser(id);
	this->_user.erase(user->GetId());
	delete user;
}

bool			AgoraAdmin::UserManager::UserExists(const std::string& login)
{
	IDatabase::DbResult*	result = Configuration::GetConfiguration()->GetDatabase()->SelectUser(login);

	if (result->size())
		return true;
	return false;
}